<?php
class ConsultaModel extends CustomModel
{

    public function getGrupos()
    {
        $gruposAbm = new ABM('grupos');
        return $gruposAbm->get(array('status' => STATUS_ONLINE));
    }

    public function getGrupo($id)
    {
        $gruposAbm = new ABM('grupos');
        return $gruposAbm->get(array('idgrupo' => $id, 'status' => STATUS_ONLINE));
    }

    public function getPuntos($fkGrupo)
    {
        $geolocalizacionesAbm = new ABM('geolocalizaciones');
        $rutas = $this->db->select('fkruta')->from('viajes')->where(filter('fkgrupo', '=', $fkGrupo))->groupBy('fkruta')->get();
        if (!empty($rutas))
        {
            $rutasIds = array();
            foreach ($rutas as $ruta)
            {
                $rutasIds[] = $ruta['fkruta'];
            }
            $puntosAbm = new ABM('puntos_por_ruta');
            return $puntosAbm->getWithJoin(array('fkruta' => $rutasIds), array('rutas' => array('rutas.idruta' => 'puntos_por_ruta.fkruta')));
        }
        else
        {
            return false;
        }
    }

    public function getPunto($idPunto)
    {
        $puntosPorRutaAbm = new ABM('puntos_por_ruta');
        $punto = $puntosPorRutaAbm->get(array('idpunto_por_ruta' => $idPunto));
        if ($punto)
        {
            $punto = $punto[$idPunto];
            // Determinar si hay algun viaje en curso para esta ruta
            $joins = array(
                'conductores' => array('viajes.fkconductor' => 'conductores.idconductor'),
                'vehiculos'   => array('viajes.fkvehiculo'  => 'vehiculos.idvehiculo'),
            );
            $viajesAbm = new ABM('viajes');
            $viajes = $viajesAbm->getWithJoin(array('fkruta' => $punto['fkruta'], 'status' => STATUS_ONLINE), $joins);
            if ($viajes)
            {
                // Get geolocalizaciones info de este punto
                $proximoFilter = filter('fkproximo_punto', '=', $idPunto);
                $puntoFilter   = filter('fkpunto_por_ruta', '>', 0);
                $filter        = filter($proximoFilter, 'OR', $puntoFilter);
                $viajeFilter   = filter('fkviaje', 'IN', array_keys($viajes));
                $filter        = filter($filter, 'AND', $viajeFilter);
                $geolocalizacionesABM = new ABM('geolocalizaciones');
                $geolocalizacionesDelViaje = $geolocalizacionesABM->get($filter, array('idgeolocalizacion ASC'));
                if (!empty($geolocalizacionesDelViaje))
                {
                    foreach ($geolocalizacionesDelViaje as $geoloc)
                    {
                        $viajes[$geoloc['fkviaje']]['geolocalizaciones'][]=$geoloc;
                    }
                    $horariosLlegada = array();
                    foreach ($viajes as $viaje)
                    {
                        $horarioInfo = false;
                        if (!empty($viaje['geolocalizaciones']))
                        {
                            $mustCalc = false;
                            $i = 0;
                            foreach($viaje['geolocalizaciones'] as $viajeLoc)
                            {
                                $i++;
                                if ($viajeLoc['fkpunto_por_ruta'] >= $idPunto)
                                {
                                    $horarioInfo = false;
                                    break;
                                }
                                else if ($viajeLoc['fkproximo_punto'] == $idPunto)
                                {
                                    if (empty($horarioInfo['viaje']) || ($viajeLoc['idgeolocalizacion'] > $horarioInfo['idgeolocalizacion']))
                                    {
                                        $auxViaje = $viaje;
                                        unset($auxViaje['geolocalizaciones']);
                                        $horarioInfo = array(
                                            'idgeolocalizacion' => $viajeLoc['idgeolocalizacion'],
                                            'viaje'             => $auxViaje,
                                            'llegada_timestamp' => $viajeLoc['proximo_punto_timestamp']
                                        );
                                    }
                                }
                                else
                                {
                                    // Se necesita calcular para este punto, a partir de la ultima obtenida
                                    if($i == count($viaje['geolocalizaciones']))
                                    {
                                        // Estimacion de tiempos. Para ello obtenemos la ruta entera
                                        $puntosDeLaRuta = $puntosPorRutaAbm->get(array('fkruta' => $punto['fkruta']));
                                        if (!empty($puntosDeLaRuta))
                                        {
                                            // Franjas fix
                                            $puntosFranja    = array();
                                            $puntosFranjaABM = new ABM('tiempo_por_franja_por_punto');
                                            $franjaJoin      = array(
                                                'franjas' => array('tiempo_por_franja_por_punto.fkfranja' => 'franjas.idfranja')
                                            );
                                            $puntosFranjaAux = $puntosFranjaABM->getWithJoin(array('fkpunto_por_ruta' => array_keys($puntosDeLaRuta)), $franjaJoin, false, false, false);
                                            if (!empty($puntosFranjaAux))
                                            {
                                                $puntosFranja = array();
                                                foreach($puntosFranjaAux as $punto)
                                                {
                                                    $puntosFranja[$punto['fkpunto_por_ruta']][] = $punto;
                                                }
                                            }
                                            // Calcular tiempo
                                            $auxViaje = $viaje;
                                            unset($auxViaje['geolocalizaciones']);
                                            $ultimaLecturaTs = $viajeLoc['fecha_timestamp'];
                                            $ultimoPunto     = $viajeLoc['fkpunto_por_ruta'];
                                            $auxTimestamp    = $ultimaLecturaTs;
                                            $horarioInfo = array(
                                                'viaje'             => $auxViaje,
                                                'llegada_timestamp' => $ultimaLecturaTs
                                            );
                                            foreach ($puntosDeLaRuta as $punto)
                                            {
                                                if (($punto['idpunto_por_ruta'] > $ultimoPunto) && ($punto['idpunto_por_ruta'] <= $idPunto))
                                                {
                                                    if (!empty($puntosFranja[$punto['idpunto_por_ruta']]))
                                                    {
                                                        $auxDiaTimestamp  = mktime(0,0,0,date('m', $horarioInfo['llegada_timestamp']), date('d', $horarioInfo['llegada_timestamp']), date('y', $horarioInfo['llegada_timestamp']));
                                                        // Tiempo segun franja necesario?
                                                        $diaSemana = date('N', $horarioInfo['llegada_timestamp']);
                                                        switch($diaSemana)
                                                        {
                                                            case '1': $bitmap = BITMAP_LUNES; break;
                                                            case '2': $bitmap = BITMAP_MARTES; break;
                                                            case '3': $bitmap = BITMAP_MIERCOLES; break;
                                                            case '4': $bitmap = BITMAP_JUEVES; break;
                                                            case '5': $bitmap = BITMAP_VIERNES; break;
                                                            case '6': $bitmap = BITMAP_SABADO; break;
                                                            case '7': $bitmap = BITMAP_DOMINGO; break;
                                                        }
                                                        foreach ($puntosFranja[$punto['idpunto_por_ruta']] as $franja)
                                                        {
                                                            if (($franja['dias'] & $bitmap) > 0)
                                                            {
                                                                $auxHorarioLectura  = $horarioInfo['llegada_timestamp'] - $auxDiaTimestamp;
                                                                if (($auxHorarioLectura >= $franja['horario_desde']) && ($auxHorarioLectura <= $franja['horario_hasta']))
                                                                {
                                                                    $punto['segundos_anterior'] = $franja['segundos_anterior'];
                                                                }
                                                            }
                                                        }
                                                    }
                                                    $horarioInfo['llegada_timestamp'] += $punto['segundos_anterior'];
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if ($horarioInfo)
                        {
                            $horarioInfo['llegada'] = date('d/m/Y H:i:s', $horarioInfo['llegada_timestamp']);
                            $horarioInfo['tiempo']  = $horarioInfo['llegada_timestamp'];
                            $horariosLlegada[]=$horarioInfo;
                        }
                    }
                    usort($horariosLlegada, 'sortTs');
                    return $horariosLlegada;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

}

function sortTs($a, $b)
{
    return ($a['tiempo'] < $b['tiempo']) ? -1 : 1;
}
?>